import java.awt.Graphics2D;
import java.util.List;

import com.golden.gamedev.GameEngine;
import com.golden.gamedev.GameObject;
import com.golden.gamedev.object.PlayField;

/**
 * 
 * Like in theater, Scenes are self-contained units of a game. The motivation
 * behind having a scene is that resources specific to a part of the game should
 * only be initialized when that part of the game is reached. A scene also facilitates
 * transitioning between Scenes because in the exit method you can setup up which 
 * Scene to transition to by using the endScene method of GameFlow.
 * 
 * In normal use of Scene, init will be called to initialize required objects. Init can
 * call setProps to initialize objects pertaining to game state. For example, the user can reset
 * back to a check point by calling setProps. Then normal update and render will be called. There is an
 * instance of playField in the scene, and this will help user manage contents of this scene.
 * Finally, when the scene needs to end, the exit method will be called. The exit method will clean up
 * the Scene by deactivating all that needs to be deactivated. The exit method should also tell the GameFlow
 * which scene is next.
 * 
 * @author KevinWang
 *
 */
public abstract class Scene {
    
    protected PlayField playField;
    protected GameFlow game;
    
 

    public Scene(GameFlow game){
        this(new PlayField(), game);
        init(null);
    }
           

    
    public Scene(PlayField playField, GameFlow game) {
		this.playField=playField;
		this.game=game;
		init(null);
    }


    /**
     * initialize the required resource for the Scene
     * 
     * @param args
     */
	protected abstract void init(Object[] args);
    
	
	/**
	 * Exit the current scene and transition to the next scene.
	 * 
	 * @param nextSceneName - name of the next scene
	 * @param params -additional parameters passed along
	 */
    public void exit(String nextSceneName, List<Object> params){
        cleanUp();
        game.endScene(nextSceneName, params);
    }
    
    /**
     * A clean up method that will handle all the clean up required to make 
     * the game run faster
     */
    protected abstract void cleanUp();

    /**
     * update all elements in this scene
     * @param elapsedTime - time since last update
     */
    public abstract void update(long elapsedTime);
    
    /**
     * render all elements in this scene
     * @param g - graphics2D to draw
     */
    public abstract void render(Graphics2D g);

    /**
     * Set up the scene for different states/check points
     * 
     * @param params
     */
	public abstract void setProps(Object[] params);
    
}
